package glemipsc;

import java.io.*;
import java.util.*;

%%

%standalone
%unicode
%class PreParser
%line
%column

%xstate macro
%xstate include
%xstate deletenr
%xstate comment
%xstate line_comment

%{
	private ArrayList<String> includePath = new ArrayList<String>();
	private HashMap<String,StringBuffer> macros = new HashMap<String,StringBuffer>();
	private String currentMacroName;
	
	private PrintStream out = System.out;
	
	public void setOutputStream(PipedOutputStream stream) {
		out = new PrintStream(stream);
	}
	
	public void setIncludePath(ArrayList<String> includes) {
		this.includePath = includes;
	}

	
	private File includeFile(String fileName) throws IOException {
		if (fileName.startsWith("\"") && fileName.endsWith("\"")){
			File file = new File("./"+fileName.substring(1, fileName.length()-1));
			if (file.exists()){
				return file;
			/*}else{
				for (int i = 0; i < includePath.size(); i++) {
				file = new File(includePath.get(i) + "/" + fileName.substring(1, fileName.length()-1));
				if (file.exists())
					return file;
				}*/
			
			}
		}else if (fileName.startsWith("<") && fileName.endsWith(">")){
			for (int i = 0; i < includePath.size(); i++) {
				File file = new File(includePath.get(i) + "/" + fileName.substring(1, fileName.length()-1));
				if (file.exists())
					return file;
		}
			}
		return null;
	}

  

%}

identifier = [a-zA-Z_][a-zA-Z0-9]*
includeFile = ("<"|"\"")[a-zA-Z\._0-9/-]+(">"|"\"")

nl = \n | \r | \r\n

%%

"/*"                 {yybegin(comment);}
<comment>[^*]*       {;}
<comment>"*"+[^*/]*  {;}
<comment>"*"+"/"     {yybegin(YYINITIAL);}
"/"+"/"                 {yybegin(line_comment);}
<line_comment>{nl}   {yybegin(YYINITIAL);}
<line_comment>.      {;}

"#define"			{ yybegin(macro); }
<macro> "\\"{nl}|.		{ if (currentMacroName != null) macros.get(currentMacroName).append(yytext().startsWith("\\") ? yytext().substring(1) : yytext()); }
<macro>{nl}			{ currentMacroName = null; yybegin(YYINITIAL);}
<macro>{identifier}		{
					if (currentMacroName == null) {
						currentMacroName = yytext();
						macros.put(currentMacroName, new StringBuffer());
					}
					else
						macros.get(currentMacroName).append(yytext());
				}

"#include"			{ yybegin(include); }
<include> {includeFile}		{
					File file = includeFile(yytext());
					if (file != null) {
						FileReader includeReader = new FileReader(file);
						yypushStream(includeReader);
					}
					yybegin(YYINITIAL);
				}
<include>[ \t]*		{;}

{identifier}			{
					StringBuffer content = macros.get(yytext());
					if (content != null)
						out.print(content);
					else
						out.print(yytext());

				}

				
<deletenr>[ \t\n\r]* {yybegin(YYINITIAL);}

<<EOF>>				{
						if (yymoreStreams()) {
							yypopStream();
							yybegin(deletenr);
							
						}else {
							out.close();
							return YYEOF;
						}
					}

.|{nl} { out.print(yytext()); }

